package com.je.app.control;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JPanel;
import javax.swing.table.DefaultTableModel;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import com.je.app.control.interfaces.ControlTurnoInterface;
import com.je.app.model.BajaConsumicion;
import com.je.app.model.Consumicion;
import com.je.app.model.Habitacion;
import com.je.app.model.Sesion;
import com.je.app.model.Turno;
import com.je.app.persistence.DaoHabitacion;
import com.je.app.persistence.DaoStock;
import com.je.app.persistence.DaoTurno;
import com.je.app.view.MainFrame;
import com.je.app.view.MainFrame.MessageType;
import com.je.app.view.Turnos;
import com.je.app.view.popUp.AgregarConsumicion;
import com.je.app.view.popUp.ModificarTurno;


public class ControlTurno implements ControlTurnoInterface{

	private static ControlTurno instance;
	private MainFrame mainFrame ;
	private DaoTurno daoTurno = DaoTurno.getInstance();
	private DaoHabitacion daoHabitacion = DaoHabitacion.getInstance();
	
	List <Habitacion> habitaciones;
	List <Turno> turnos;
	Turno turnoSeleccionado = null;
	private List <BajaConsumicion> listaConsumiciones;
	private ModificarTurno ventanaModificarTurno;
	
	public static ControlTurno getInstance(){
		if(instance==null){
			instance = new ControlTurno();
		}
		return instance;
	}
	
	private ControlTurno(){
		mainFrame = MainFrame.getInstance();
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void abrirTurnos(){

		habitaciones = daoHabitacion.list(Habitacion.class.getName());
		Sesion sesionActual = ControlSesion.getInstance().getActiveSesion();
		turnos = daoTurno.list(sesionActual);

		Object[][] modelTurnos = new Object[turnos.size()][6] ;
		
		for(int i = 0 ; i < turnos.size() ; i++){
			modelTurnos[i] = turnos.get(i).toArray();
		}

		DefaultComboBoxModel modelHabitaciones = new DefaultComboBoxModel();
		
		modelHabitaciones.addElement("Todas");
		for(Habitacion habitacion: habitaciones){
			modelHabitaciones.addElement(habitacion.getNombre());
		}
		
		JPanel panel = new Turnos(modelTurnos, modelHabitaciones,null);
		mainFrame.setPanel(panel);
	}
	
	@SuppressWarnings("unchecked")
	public void buscarTurnos(Date fecha, Integer rowHabitacion){
		Integer id = null;
		if(rowHabitacion>0){
			id = habitaciones.get(rowHabitacion-1).getIdHabitacion();
		}
		turnos = daoTurno.filter(fecha, id);
		List <Object[]> list = new ArrayList <Object[]>();
		for(Turno turno: turnos){
			list.add(turno.convertArray());
		}
		
		mainFrame.setTableModel("turnos", list);
	}

	public void buscarTurno(int rowTable) {
		turnoSeleccionado = turnos.get(rowTable);
		Set <BajaConsumicion> consumiciones = turnoSeleccionado.getBajaConsumicions();
		
		List <Object[]> list = new ArrayList <Object[]>();
		for(BajaConsumicion consumicion : consumiciones){
			list.add(consumicion.toArray());
		}
		
		
		Object [] valores = turnoSeleccionado.toArray();
		mainFrame.setProperty("Fecha", valores[0]);
		mainFrame.setProperty("Habitacion", valores[1]);
		//mainFrame.setProperty("Usuario", valores[2]);
		mainFrame.setProperty("Hora de entrada", valores[3]);
		mainFrame.setProperty("Hora de salida", valores[4]);
		mainFrame.setProperty("Tiempo", turnoSeleccionado.getTiempoTotal());
		mainFrame.setProperty("Importe", valores[6]);
		mainFrame.setProperty("Consumicion", valores[7]);
		mainFrame.setProperty("Total", valores[8]);
		mainFrame.setTableModel("consumiciones", list);
	}

	public void mostrarModificarTurno() {
		if(turnoSeleccionado==null){
			mainFrame.showMessage(MessageType.ERROR,"Debe seleccionar un turno");
		}
		else if(!turnoSeleccionado.getSesion().equals(ControlSesion.getInstance().getActiveSesion())){
			//No pertenece a la seccion activa
			mainFrame.showMessage(MessageType.ERROR,"Este turno no corresponde a la sesi\u00F3n actual");
		}
		else{

			Set <BajaConsumicion> consumiciones = turnoSeleccionado.getBajaConsumicions();
			listaConsumiciones = new ArrayList <BajaConsumicion> ();
			Object[][] modelConsumiciones = new Object[consumiciones.size()][3];
			int i=0;
			for(BajaConsumicion consumicion : consumiciones){
				listaConsumiciones.add(consumicion);
				modelConsumiciones[i] = consumicion.toArray();
				i++;

			}
			String [] listaHabitaciones = new String[habitaciones.size()];
			int index = 0;
			for(Habitacion hab : habitaciones){
				listaHabitaciones[index] = hab.getNombre();
				index++;
			}
			Object [] valores = turnoSeleccionado.toArray();

			String horaEntrada = (String) valores[3];
			String horaSalida = (String) valores[4];
			String tiempo = turnoSeleccionado.getTiempoTotal();
			String importe = "" + valores[6];
			String consumicion = "" + valores[7];
			String total = "" + valores[8];
			ventanaModificarTurno = new ModificarTurno(listaHabitaciones,turnoSeleccionado.getHabitacion().getNombre(),turnoSeleccionado.getHoraInicio(),horaEntrada,horaSalida,tiempo,importe,consumicion,total,modelConsumiciones);
			 
			
		}
	}
	
	public void modificarTurno(double montoHabitacion, Date horaInicio, Date horaFin, String nombreHabitacion){
		try{
			Habitacion habitacionSeleccionada = null;
			for(Habitacion hab : habitaciones){
				if(hab.getNombre().equals(nombreHabitacion))
					habitacionSeleccionada = hab;
			}
			if(turnoSeleccionado!=null){
				turnoSeleccionado.setMontoHabitacion(montoHabitacion);
				turnoSeleccionado.setHoraFin(horaFin);
				turnoSeleccionado.setHoraInicio(horaInicio);
				turnoSeleccionado.setHabitacion(habitacionSeleccionada);
				ControlSesion.getInstance().getActiveSesion().recalcularSaldo();
				DaoTurno.getInstance().persist(turnoSeleccionado);
				turnoSeleccionado=null;
				abrirTurnos();
				mainFrame.showMessage(MessageType.EXITO, null); //MUESTRA MENSAJE CONFIRMACION
			}
		}catch(ConstraintViolationException cve){
			//mensajes error
			cve.printStackTrace();
			for(ConstraintViolation constraintViolation : cve.getConstraintViolations()){
				mainFrame.setErrorMessage(constraintViolation.getPropertyPath().toString(), constraintViolation.getMessage());
			}

		}
	}
	
	public void mostrarAgregarConsumicion(String nombreHabitacion) {
	
		List <Consumicion> consumiciones = DaoStock.getInstance().list(Consumicion.class.getName());
	
		String [] list = new String[consumiciones.size()+1];
		list[0] = "";
		for(int i=1; i<=consumiciones.size();i++){
			Consumicion cons = consumiciones.get(i-1);
			list[i]=cons.getNombre();
		}
		
		//crear emergente pasando como parametro list consumiciones
		new AgregarConsumicion(nombreHabitacion,list,"TURNO_FINALIZADO");
		
	}

	public void agregarConsumicion(int cantidad, String nombreConsumicion, String nombreHabitacion) {
		//  crear consumicion - validar que quede stock

		if(turnoSeleccionado == null) {
			//turno no valido o similar
			mainFrame.showMessage(MessageType.ERROR, "NO EXISTE EL TURNO. COMUNICARSE CON EL ADMINISTRADOR.");

		}
		else{
			Consumicion consumicionSeleccionada = null;
			List <Consumicion> consumiciones = DaoStock.getInstance().list(Consumicion.class.getName());
			for(Consumicion cons: consumiciones){
				if(cons.getNombre().equals(nombreConsumicion)){
					consumicionSeleccionada = cons;
				}
			}

			
			if(consumicionSeleccionada.getStockHeladera()<cantidad){
				//error stock insuficiente
				 mainFrame.showMessage(MessageType.ERROR, "No hay stock suficiente para realizar esta venta");
				
			}
			else{
				BajaConsumicion baja = new BajaConsumicion(consumicionSeleccionada,ControlSesion.getInstance().getActiveSesion(),turnoSeleccionado,cantidad,0,cantidad*consumicionSeleccionada.getPrecioUnitario(),"");
				consumicionSeleccionada.addBajaConsumicion(baja);
				turnoSeleccionado.addConsumicion(baja);

				daoHabitacion.save(BajaConsumicion.class.getName(), baja);
				daoHabitacion.persist(consumicionSeleccionada);
				daoHabitacion.persist(turnoSeleccionado);
				listaConsumiciones.add(baja);
				Object [] fila = new Object[]{cantidad,nombreConsumicion,baja.getMontoTotal()};
				ventanaModificarTurno.agregarFilaConsumicion(fila);
				mainFrame.showMessage(MessageType.EXITO,null);

			}
		}
	}
	
	public void eliminarConsumicion(String nombreHabitacion, int rowConsumicion){
		
		boolean confirmado = mainFrame.showMessage(MessageType.CONFIRMACION, null);
		
		if(confirmado){
			//consumiciones
			BajaConsumicion baja  = listaConsumiciones.get(rowConsumicion);

			Turno turnoSeleccionado = null;
			for(Turno turno: turnos){
				if(turno.getHabitacion().getNombre().equals(nombreHabitacion)){
					turnoSeleccionado = turno;
				}
			}

			baja.getConsumicion().removeBajaConsumicion(baja);
			turnoSeleccionado.removeConsumicion(baja);
			daoTurno.remove(baja);
			ventanaModificarTurno.eliminarFilaConsumicion(rowConsumicion);
			mainFrame.showMessage(MessageType.EXITO, null); //MUESTRA MENSAJE CONFIRMACION

		}
		
	}

	


}
